#include "../dish.h"
#include "test_utilities.h"
#include <stdbool.h>
#include <string.h>

#define ASSERT_NULL(a) ASSERT_TEST((a)==NULL)
#define ASSERT_EQUAL(a,b) ASSERT_TEST((a)==(b))
#define ASSERT_STRING_EQUAL(a,b) ASSERT_TEST(strcmp((a),(b))==0)

static bool testDishCreate() {
	DishResult result;
	Dish dish;
	result=DISH_OUT_OF_MEMORY;
	dish=dishCreate(NULL,ENTREE,1,1,1,&result);
	ASSERT_EQUAL(result,DISH_INVALID_ARGUMENT);
	ASSERT_NULL(dish);
	result=DISH_OUT_OF_MEMORY;
	dish=dishCreate("myDish",ENTREE,11,1,1,&result);
	ASSERT_EQUAL(result,DISH_INVALID_ARGUMENT);
	ASSERT_NULL(dish);
	result=DISH_OUT_OF_MEMORY;
	dish=dishCreate("myDish",ENTREE,1,11,1,&result);
	ASSERT_EQUAL(result,DISH_INVALID_ARGUMENT);
	ASSERT_NULL(dish);
	result=DISH_OUT_OF_MEMORY;
	dish=dishCreate("myDish",ENTREE,1,1,11,&result);
	ASSERT_EQUAL(result,DISH_INVALID_ARGUMENT);
	ASSERT_NULL(dish);
	result=DISH_OUT_OF_MEMORY;
	dish=dishCreate("myDish",-1,1,1,1,&result);
	ASSERT_EQUAL(result,DISH_INVALID_ARGUMENT);
	ASSERT_NULL(dish);
	ASSERT_NULL(dishCreate("myDish",ENTREE,0,1,1,NULL));
	dish=dishCreate("myDish",ENTREE,10,10,1,&result);
	ASSERT_EQUAL(result,DISH_SUCCESS);
	ASSERT_TEST(dish);
	dishDestroy(dish);
	return true;
}

static bool testDishCopy() {
	Dish dish1=dishCreate("myDish",ENTREE,10,7,1,NULL);
	DishResult result=DISH_OUT_OF_MEMORY;
	ASSERT_NULL(dishCopy(NULL,NULL));
	ASSERT_NULL(dishCopy(NULL,&result));
	ASSERT_EQUAL(result,DISH_INVALID_ARGUMENT);
	Dish dish2=dishCopy(dish1,&result);
	ASSERT_TEST(dish2);
	ASSERT_EQUAL(result,DISH_SUCCESS);
	ASSERT_EQUAL(dishGetType(dish2),ENTREE);
	ASSERT_EQUAL(dishGetSweetness(dish2),10);
	ASSERT_EQUAL(dishGetSourness(dish2),7);
	ASSERT_EQUAL(dishGetSaltiness(dish2),1);
	ASSERT_STRING_EQUAL(dishGetName(dish2),"myDish");
	dishDestroy(dish1);
	dishDestroy(dish2);
	return true;
}


static bool testDishDestroy() {
	dishDestroy(NULL);
	Dish dish=dishCreate("myDish",ENTREE,10,10,1,NULL);
	dishDestroy(dish);
	return true;
}

static bool testDishGetName() {
	ASSERT_NULL(dishGetName(NULL));
	Dish dish=dishCreate("myDish",ENTREE,10,9,8,NULL);
	ASSERT_STRING_EQUAL(dishGetName(dish),"myDish");
	dishDestroy(dish);
	return true;
}

static bool testDishGetType() {
	ASSERT_EQUAL(dishGetType(NULL),DISH_NUM_OF_TYPES);
	Dish dish=dishCreate("myDish",ENTREE,10,9,8,NULL);
	ASSERT_EQUAL(dishGetType(dish),ENTREE);
	dishDestroy(dish);
	return true;
}

static bool testDishGetSweetness() {
	ASSERT_EQUAL(dishGetSweetness(NULL),0);
	Dish dish=dishCreate("myDish",ENTREE,10,9,8,NULL);
	ASSERT_EQUAL(dishGetSweetness(dish),10);
	dishDestroy(dish);
	return true;
}

static bool testDishGetSourness() {
	ASSERT_EQUAL(dishGetSourness(NULL),0);
	Dish dish=dishCreate("myDish",ENTREE,10,9,8,NULL);
	ASSERT_EQUAL(dishGetSourness(dish),9);
	dishDestroy(dish);
	return true;
}

static bool testDishGetSaltiness() {
	ASSERT_EQUAL(dishGetSaltiness(NULL),0);
	Dish dish=dishCreate("myDish",ENTREE,10,9,8,NULL);
	ASSERT_EQUAL(dishGetSaltiness(dish),8);
	dishDestroy(dish);
	return true;
}

static bool testDishIsEdible() {
	ASSERT_TEST(!dishIsEdible(NULL));
	Dish dish1=dishCreate("myDish",ENTREE,9,7,5,NULL);
	Dish dish2=dishCreate("myDish",ENTREE,10,7,5,NULL);
	Dish dish3=dishCreate("myDish",ENTREE,9,8,5,NULL);
	Dish dish4=dishCreate("myDish",ENTREE,9,7,6,NULL);
	ASSERT_TEST(dishIsEdible(dish1));
	ASSERT_TEST(!dishIsEdible(dish2));
	ASSERT_TEST(!dishIsEdible(dish3));
	ASSERT_TEST(!dishIsEdible(dish4));
	dishDestroy(dish1);
	dishDestroy(dish2);
	dishDestroy(dish3);
	dishDestroy(dish4);
	return true;
}

int main() {
	RUN_TEST(testDishCreate);
	RUN_TEST(testDishCopy);
	RUN_TEST(testDishDestroy);
	RUN_TEST(testDishGetName);
	RUN_TEST(testDishGetType);
	RUN_TEST(testDishGetSweetness);
	RUN_TEST(testDishGetSourness);
	RUN_TEST(testDishGetSaltiness);
	RUN_TEST(testDishIsEdible);
	return 0;
}
